package com.tt.fashionWebSite.service.imp;

import com.tt.fashionWebSite.dao.HoaDonFullDao;
import com.tt.fashionWebSite.dao.SanPhamFullDao;
import com.tt.fashionWebSite.dao.TapLuatKetHopDao;
import com.tt.fashionWebSite.domain.*;
import com.tt.fashionWebSite.dto.*;
import com.tt.fashionWebSite.service.Ad_RuleService;
import com.tt.fashionWebSite.service.GenericService;
import com.tt.fashionWebSite.util.Rule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by isoft-work 5 on 1/11/2015.
 */
@Service("ad_RuleService")
public class Ad_RuleServiceImp extends GenericService implements Ad_RuleService {
   @Autowired
   @Qualifier("hoaDonFull")
   private HoaDonFullDao hoaDonFullDao;

   @Autowired
   @Qualifier("sanPhamFull")
   private SanPhamFullDao sanPhamFullDao;

   @Autowired
   @Qualifier("tapLuatKetHop")
   private TapLuatKetHopDao tapLuatKetHopDao;

   @Override
   public List<RuleOutputDto> getRule(RuleInputDto ruleInputDto) {
      List<RuleOutputDto> reRuleOutputs = new ArrayList<RuleOutputDto>();
      List<HoaDonFullDto> hoaDonFulls = hoaDonFullDao.getAllDetailBill();
      List<SanPhamRuleDto> sanPhamFulls = sanPhamFullDao.getProductAll();
      Integer[][] maTrix;
      maTrix = getMatrix(hoaDonFulls, sanPhamFulls);
      Rule rule = new Rule(maTrix, sanPhamFulls.size(), hoaDonFulls.size(), ruleInputDto.getMinSupp(), ruleInputDto.getMinConfig());
      rule.runRule();
      List<List<Integer>> left = rule.getLeft();
      List<List<Integer>> right = rule.getRight();
      List<Double> cf = rule.getCF();

      if (left.size() > 0) {
         for (int i = 0; i < left.size(); i++) {
            RuleOutputDto ruleOutputDto = new RuleOutputDto();
            List<Integer> l = left.get(i);
            List<Integer> r = right.get(i);
            String leftId = "";
            String rightId = "";
            String percent = String.valueOf(cf.get(i) * 100);
            String ruleString = "";
            String leftString = "";
            String rightString = "";

            for (int j = 0; j < l.size(); j++) {
               ruleString += sanPhamFulls.get(l.get(j)).getTenSP();

               if(j == l.size() - 1) {
                  leftString += sanPhamFulls.get(l.get(j)).getTenSP();
                  leftId += sanPhamFulls.get(l.get(j)).getMaSP();
               }
               else {
                  leftString += sanPhamFulls.get(l.get(j)).getTenSP() + ", ";
                  leftId += sanPhamFulls.get(l.get(j)).getMaSP() + "^";
               }
            }
            ruleString += "->";
            for (int j = 0; j < r.size(); j++) {
               ruleString += sanPhamFulls.get(r.get(j)).getTenSP();

               if(j == r.size() - 1) {
                  rightString += sanPhamFulls.get(r.get(j)).getTenSP();
                  rightId += sanPhamFulls.get(r.get(j)).getMaSP();
               }
               else {
                  rightString += sanPhamFulls.get(r.get(j)).getTenSP() + ", ";
                  rightId += sanPhamFulls.get(r.get(j)).getMaSP() + "^";
               }
            }

            ruleOutputDto.setLeftId(leftId);
            ruleOutputDto.setRightId(rightId);
            ruleOutputDto.setLeft(leftString);
            ruleOutputDto.setRight(rightString);
            ruleOutputDto.setLuat(ruleString);
            ruleOutputDto.setPhanTram(percent);
            reRuleOutputs.add(ruleOutputDto);
         }
         return reRuleOutputs;
      }
      return null;
   }

   private Integer[][] getMatrix(List<HoaDonFullDto> hoaDonFulls, List<SanPhamRuleDto> sanPhamFulls) {
      Integer[][] matrix = new Integer[hoaDonFulls.size()][sanPhamFulls.size()];
      for(int h = 0; h < hoaDonFulls.size(); h++) {
         List<ChiTietHoaDonFullDto> chiTietHoaDonFulls = hoaDonFulls.get(h).getChiTietHoaDon();
         if(chiTietHoaDonFulls == null || chiTietHoaDonFulls.size() == 0) {
            for(int s = 0; s < sanPhamFulls.size(); s++) {
               matrix[h][s] = 0;
            }
         }
         else {
            for(int s = 0; s < sanPhamFulls.size(); s++) {
               List<ChiTietSanPhamRuleDto> chiTietSanPhamFulls = sanPhamFulls.get(s).getChiTietSanPhams();
               if(chiTietSanPhamFulls == null || chiTietSanPhamFulls.size() == 0) {
                  matrix[h][s] = 0;
               }
               else {
                  for(int ch = 0; ch < chiTietHoaDonFulls.size(); ch++) {
                     boolean c = false;
                     for(int cs = 0; cs < chiTietSanPhamFulls.size(); cs++) {
                        String id1 = chiTietHoaDonFulls.get(ch).getChiTietSanPham().getMaCTSP();
                        String id2 = chiTietSanPhamFulls.get(cs).getMaCTSP();
                        if(id1.equals(id2)) {
                           matrix[h][s] = 1;
                           c = true;
                           break;
                        }
                        else {
                           if(ch == chiTietHoaDonFulls.size() - 1) {
                              matrix[h][s] = 0;
                           }
                        }
                     }
                     if(c) {
                        break;
                     }
                  }
               }
            }
         }
      }
      return matrix;
   }

   @Override
   @Transactional(propagation = Propagation.REQUIRED)
   public int updateRule(List<RuleOutputDto> ruleOutputDtos) {
      try {
         tapLuatKetHopDao.deleteAll();
         for(int i = 0; i < ruleOutputDtos.size(); i++) {
            RuleOutputDto ruleOutputDto = ruleOutputDtos.get(i);
            TapLuatKetHop tapLuatKetHop = new TapLuatKetHop();

            tapLuatKetHop.setVePhaiMASP(ruleOutputDto.getRightId());
            tapLuatKetHop.setVePhaiTenSP(ruleOutputDto.getRight());
            tapLuatKetHop.setVeTraiMaSP(ruleOutputDto.getLeftId());
            tapLuatKetHop.setVeTraiTenSP(ruleOutputDto.getLeft());
            tapLuatKetHop.setPhanTram(Double.valueOf(ruleOutputDto.getPhanTram()));
            tapLuatKetHopDao.insert(tapLuatKetHop);
         }
         return JsonResponseCode.SUCCESS;
      }
      catch (Exception ex) {
         return JsonResponseCode.FAILED;
      }
   }

   @Override
   public List<TapLuatKetHopDto> getRuleOut() {
      List<TapLuatKetHopDto> tapLuatKetHopDtos = mapper.mapCollection(tapLuatKetHopDao.getAll(), TapLuatKetHopDto.class);
      if(tapLuatKetHopDtos != null && tapLuatKetHopDtos.size() > 0) {
         return tapLuatKetHopDtos;
      }
      return null;
   }
}
